package com.kerwin.springcloud.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.kerwin.springcloud.entities.CommonResult;
import com.kerwin.springcloud.entities.Payment;
import com.kerwin.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

@RestController
@Slf4j
public class OrderController {
    public static final String INVOKE_URL = "http://nacos-payment-provider";

    @Resource
    private RestTemplate restTemplate;
    @Resource
    private PaymentService paymentService;

    @GetMapping(value = "/consumer/paymentSql/{id}")
//    @SentinelResource(value = "paymentSql") // 没有配置
//    @SentinelResource(value = "paymentSql", fallback = "fallbackHandler") // fallbackHandler负责业务异常
//    @SentinelResource(value = "paymentSql", blockHandler = "blockHandler") // blockHandler负责sentinel控制台配置违规
//    @SentinelResource(value = "paymentSql", fallback = "fallbackHandler", blockHandler = "blockHandler") // fallbackHandler + blockHandler，blockHandler优先级高于fallbackHandler
    @SentinelResource(value = "paymentSql", fallback = "fallbackHandler", blockHandler = "blockHandler", exceptionsToIgnore = {IllegalArgumentException.class})
    public CommonResult<Payment> paymentSql(@PathVariable("id") Long id){
        CommonResult<Payment> result = restTemplate.getForObject(INVOKE_URL + "/paymentSql/" + id, CommonResult.class);
        if (id == 4){
            throw new IllegalArgumentException("IllegalArgumentException，非法参数...");
        }else if(result.getData() == null){
            throw new NullPointerException("NullPointerException，没有对应的记录，空指针异常...");
        }
        return result;
    }

    public CommonResult<Payment> fallbackHandler(@PathVariable("id") Long id, Throwable throwable){
        Payment payment = new Payment(id, null);
        return new CommonResult<>(444, "兜底异常处理fallbackHandler，exception内容：" + throwable.getMessage(), payment);
    }

    public CommonResult<Payment> blockHandler(@PathVariable("id") Long id, BlockException exception){
        Payment payment = new Payment(id, null);
        return new CommonResult<>(445, "blockHandler限流，exception内容：" + exception.getMessage(), payment);
    }

    @GetMapping(value = "/consumer/feign/{id}")
    public CommonResult<Payment> feign(@PathVariable("id") Long id){
        return paymentService.paymentSql(id);
    }
}
